classdef dotsPlayableFile < dotsPlayable
    % @class dotsPlayableFile
    % Play a sound from a .wav or .mp3 file.
    %
    % @ingroup playable
    
    properties (SetObservable = true)
        % string file name of a .wav or .mp3 file to play
        fileName;
        
        % whether to play synchonously (true) or asynchronously
        % @details
        % Be warned that using isBlocking = false can lead to errors
        % because Matlab's audioplayer class is limited.
        isBlocking = true;
    end
    
    properties (SetObservable = false)
        % Matlab audioplayer object
        player;
    end
    
    methods
        % Constructor takes no arguments.
        function self = dotsPlayableFile
            self = self@dotsPlayable;
        end
        
        % Read audio data from the the sound file.
        function prepareToPlay(self)
            fileWithPath = fullfile(self.soundsPath, self.fileName);
            [filePath, fileName, fileType] = fileparts(fileWithPath);
            
            % get waveform and properties of .wav or .mp3 files
            if strcmp(fileType, '.wav')
                % MATLAB's builtin .wav reader
                [self.waveform, self.sampleFrequency, self.bitsPerSample] = ...
                    wavread(fileWithPath);
                
            elseif strcmp(sfileType, '.mp3')
                if exist('mp3read', 'file')
                    [self.waveform, self.sampleFrequency, self.bitsPerSample] = ...
                        mp3read(fileWithPath);
                else
                    warning('%s: cannot read .mp3 files', mfilename)
                    disp(sprintf('please download the mp3read function: \n%s', ...
                        'http://www.mathworks.com/matlabcentral/fileexchange/13852-mp3read-and-mp3write'))
                end
                
            else
                disp(sprintf('%s: is %s a .wav or .mp3 file?', ...
                    mfilename, fileWithPath));
            end
            
            self.duration = length(self.waveform) ./ self.sampleFrequency;
            
            if isobject(self.player)
                self.player.stop();
                self.player = [];
            end
            
            self.player = audioplayer(self.waveform.*self.intensity, ...
                self.sampleFrequency, self.bitsPerSample);
        end
        
        % Play from the sound file.
        function play(self)
            if isobject(self.player)
                if self.isBlocking
                    self.player.playblocking();
                else
                    % asynchronous playing doesn't work well
                    self.player.play();
                end
            end
        end
    end
end